package com.gzzyy.unionchain.communicate.webrtc

import android.util.Log
import com.alibaba.fastjson.JSONObject
import com.gzzyy.unionchain.LiveEvent
import com.gzzyy.unionchain.communicate.webrtc.bean.MessageBean
import com.jeremyliao.liveeventbus.LiveEventBus
import org.webrtc.*
import java.nio.ByteBuffer
import java.util.*

class Peer(val id: String, var client: SignalingClient) : SdpObserver,
    PeerConnection.Observer, DataChannel.Observer {

    companion object {
        val TAG = Peer::class.java.simpleName

        val factory = PeerConnectionFactory(PeerConnectionFactory.Options())
        val iceServers = LinkedList<PeerConnection.IceServer>()
        val constraints = MediaConstraints()

        init {
//            iceServers.add(PeerConnection.IceServer.builder("stun:stun.l.google.com:19302").createIceServer())
//            val var11 =
//                PeerConnection.IceServer.builder("stun:47.93.186.97:3478?transport=udp")
//                    .createIceServer()
//            iceServers.add(var11)
//            val var12 =
//                PeerConnection.IceServer.builder("turn:47.93.186.97:3478?transport=udp")
//                    .setUsername("ddssingsong")
//                    .setPassword("123456")
//                    .createIceServer()
//            iceServers.add(var12)
//            val var13 =
//                PeerConnection.IceServer.builder("turn:47.93.186.97:3478?transport=tcp")
//                    .setUsername("ddssingsong")
//                    .setPassword("123456")
//                    .createIceServer()
//            iceServers.add(var13)
            iceServers.add(
                PeerConnection.IceServer
                    .builder("stun:47.114.58.183:3478?transport=udp")
                    .createIceServer()
            )
            iceServers.add(
                PeerConnection.IceServer
                    .builder("turn:47.114.58.183:3478?transport=tcp")
                    .setUsername("gzzyy007")
                    .setPassword("700yyzzg")
                    .createIceServer()
            )
            iceServers.add(
                PeerConnection.IceServer
                    .builder("turn:47.114.58.183:3478?transport=udp")
                    .setUsername("gzzyy007")
                    .setPassword("700yyzzg")
                    .createIceServer()
            )
        }
    }

    var peerConnection: PeerConnection
    var dataChannel: DataChannel

    init {
        peerConnection = factory.createPeerConnection(
            iceServers,
            constraints, this
        )
        /* DataChannel.Init 可配参数说明：
           ordered：是否保证顺序传输；
           maxRetransmitTimeMs：重传允许的最长时间；
           maxRetransmits：重传允许的最大次数；
         */
        val init = DataChannel.Init()
        init.ordered = true
        dataChannel = peerConnection.createDataChannel("dataChannel", init)
    }

    fun sendDataChannelMessage(message: String) {
        dataChannel.send(DataChannel.Buffer(ByteBuffer.wrap(message.toByteArray()), false))
    }

    fun release() {
        dataChannel.close()
        dataChannel.dispose()
        peerConnection.dispose()
    }


    //SdpObserver start-----------------------------------------------------------------------------
    override fun onSetFailure(p0: String) {

    }

    override fun onSetSuccess() {

    }

    override fun onCreateSuccess(sdp: SessionDescription) {
        val payload = JSONObject()
        payload["type"] = sdp.type.canonicalForm()
        payload["sdp"] = sdp.description
        client.sendMessage(id, sdp.type.canonicalForm(), payload.toString())
        peerConnection.setLocalDescription(this@Peer, sdp)
    }

    override fun onCreateFailure(p0: String) {
        Log.i(TAG, "sdp onCreateFailure")
    }
    //SdpObserver end-------------------------------------------------------------------------------

    //PeerConnection.Observer start-----------------------------------------------------------------
    override fun onIceCandidate(candidate: IceCandidate) {
        val payload = JSONObject()
        payload["label"] = candidate.sdpMLineIndex
        payload["id"] = candidate.sdpMid
        payload["candidate"] = candidate.sdp
        client.sendMessage(id, "candidate", payload.toString())
    }

    override fun onDataChannel(dataChannel: DataChannel) {
        dataChannel.registerObserver(this)
    }

    override fun onIceConnectionReceivingChange(p0: Boolean) {

    }

    override fun onIceConnectionChange(iceConnectionState: PeerConnection.IceConnectionState) {
        Log.d(TAG, "onIceConnectionChange : " + iceConnectionState.name)
        if (iceConnectionState === PeerConnection.IceConnectionState.DISCONNECTED) {
            //todo 通知webRtcClient 连接已断开，将其移出map中
        }
    }

    override fun onIceGatheringChange(p0: PeerConnection.IceGatheringState) {

    }

    override fun onAddStream(p0: MediaStream) {

    }

    override fun onSignalingChange(p0: PeerConnection.SignalingState) {

    }

    override fun onIceCandidatesRemoved(p0: Array<out IceCandidate>) {

    }

    override fun onRemoveStream(p0: MediaStream) {

    }

    override fun onRenegotiationNeeded() {

    }

    override fun onAddTrack(p0: RtpReceiver?, p1: Array<out MediaStream>?) {

    }
    //PeerConnection.Observer end-----------------------------------------------------------------

    //DataChannel.Observer----------------------------------------------------------------------
    override fun onBufferedAmountChange(l: Long) {

    }

    override fun onStateChange() {
        Log.d(TAG, "onDataChannel onStateChange:" + dataChannel.state())
    }

    override fun onMessage(buffer: DataChannel.Buffer) {
        val data: ByteBuffer = buffer.data
        val bytes = ByteArray(data.capacity())
        data[bytes]
        val msg = String(bytes)
        Log.d(TAG, "onDataChannel onMessage : $msg")
        LiveEventBus.get(LiveEvent.DataChannelReceiveMsg).post(MessageBean(id, msg))
    }
}